package test;

import java.io.IOException;

import neobio.alignment.BasicScoringScheme;
import neobio.alignment.IncompatibleScoringSchemeException;
import neobio.alignment.InvalidSequenceException;
import neobio.alignment.SmithWaterman;

public class SimilarityCalculator {
	private static final int MATCH_POINTS = 10;
	private static final int MISMATCH_POINTS = -1;
	private static final int GAP_POINTS = -1;

	private final SmithWaterman smithWaterman;

	public SimilarityCalculator() {
		this.smithWaterman = new SmithWaterman();
		this.smithWaterman.setScoringScheme(new BasicScoringScheme(
				SimilarityCalculator.MATCH_POINTS,
				SimilarityCalculator.MISMATCH_POINTS,
				SimilarityCalculator.GAP_POINTS));
	}

	public double match(String s1, String s2) {
		return (this.matchStrings(s1, s2) + this.matchStrings(s2, s1)) / 2;
	}

	private double matchStrings(String s1, String s2) {
		try {
			this.smithWaterman.loadSequences(s1, s2);
			int score = this.smithWaterman.getScore();
			// System.out.println(this.smithWaterman.getPairwiseAlignment()
			// .toString());
			int max = this.getMax(s1, s2);
			double v = (double) score / (double) max;
			// return Math.sqrt(v);
			return v;
		} catch (IOException e) {
			return 0;
		} catch (InvalidSequenceException e) {
			return 0;
		} catch (IncompatibleScoringSchemeException e) {
			return 0;
		}
	}

	private int getMax(String s1, String s2) {
		int l1 = s1.length();
		int l2 = s2.length();
		if (l1 > l2) {
			return l1 * SimilarityCalculator.MATCH_POINTS;
		} else {
			return l2 * SimilarityCalculator.MATCH_POINTS;
		}
	}
}
